package org.dfl.plugin.views.actions;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.dfl.core.data.History;
import org.dfl.core.data.Token;
import org.dfl.core.data.types.Type;
import org.dfl.core.data.types.TypeManager;
import org.dfl.core.model.Place;
import org.dfl.plugin.DflPlugin;
import org.dfl.plugin.dialogs.DialogsManager;
import org.dfl.plugin.views.debug.HistoriesTreeView;
import org.dfl.plugin.views.debug.TokensTreeView;
import org.dfl.plugin.views.debug.model.HistoriesTreeViewRoot;
import org.dfl.plugin.views.debug.model.HistoryTreeElem;
import org.dfl.plugin.views.debug.model.TokenTreeElem;
import org.dfl.plugin.views.debug.model.TreeElem;
import org.eclipse.jface.action.IAction;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.actions.ActionDelegate;

/**
 * action that provide pasting histories without tokens. It's used in a
 * HistoriesTreeView (see mapping in plugin.xml file)
 * 
 * @author Piotr Wlodarczyk
 * 
 */
public class PasteHistoryOnlyAction extends ActionDelegate implements
		IViewActionDelegate {
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.actions.ActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	public void run(IAction action) {
		if (view != null && view.getCommonViewer().getInput() != null
				&& view.getPlace() != null) {
			HistoriesTreeViewRoot root = (HistoriesTreeViewRoot) view
					.getCommonViewer().getInput();

			Set<TreeElem> toPasteElems = CopyContentAction.getCopyElems();
			if (toPasteElems.isEmpty()) {
				return;
			}
			for (TreeElem toPasteElem : toPasteElems) {
				if (!(toPasteElem instanceof HistoryTreeElem)
						&& !(toPasteElem instanceof TokenTreeElem)) {
					return;
				}
			}

			HistoriesTreeView historiesTreeView = HistoriesTreeView.getView();
			TokensTreeView tokensTreeView = TokensTreeView.getView();
			// place listeners have to be removed before
			if (historiesTreeView != null)
				historiesTreeView.stopListenPlace();
			if (tokensTreeView != null)
				tokensTreeView.stopListenPlace();

			Place place = view.getPlace();
			Type type = place.getTypeContainer().getType();
			Map<History, HistoryTreeElem> historiesMap = new HashMap<History, HistoryTreeElem>();
			for (TreeElem toPasteElem : toPasteElems) {
				if (toPasteElem instanceof HistoryTreeElem) {
					Set<Token> tokens = ((HistoryTreeElem) toPasteElem)
							.getTokens();
					for (Token t : tokens) {
						if (!TypeManager.isValidDataElem(t.getData(), type)) {
							DialogsManager.openErrorDialog("Wrong token types");
							return;
						}
					}
				} else {
					Token t = ((TokenTreeElem) toPasteElem).getToken();
					if (!TypeManager.isValidDataElem(t.getData(), type)) {
						DialogsManager.openErrorDialog("Wrong token types");
						return;
					}
					if (!historiesMap.containsKey(t.getHistory())) {
						historiesMap.put(t.getHistory(), new HistoryTreeElem(
								place, t.getHistory(), new HashSet<Token>()));
					}
				}
			}

			if (historiesMap.isEmpty()) {
				for (TreeElem toPasteElem : toPasteElems) {
					HistoryTreeElem historyElem = (HistoryTreeElem) toPasteElem
							.getCopy();
					historyElem.setPlace(place);
					historyElem.getTokens().clear();
					synchronized (DflPlugin.class) {
						root.addChild(historyElem);
					}
				}
			} else {
				for (History h : historiesMap.keySet()) {
					HistoryTreeElem historyElem = historiesMap.get(h);
					historyElem.setPlace(place);
					synchronized (DflPlugin.class) {
						root.addChild(historyElem);
					}
				}
			}
			// restore place listeners
			if (historiesTreeView != null)
				historiesTreeView.startListenPlace();
			if (tokensTreeView != null)
				tokensTreeView.startListenPlace();

			view.getCommonViewer().refresh();
		}
	}

	HistoriesTreeView view;

	public void init(IViewPart view) {
		if (view instanceof HistoriesTreeView)
			this.view = (HistoriesTreeView) view;
	}
}
